


// use std::{rc::Rc, cell::{RefCell}, collections::HashMap};

// use wgpu::util::DeviceExt;

// use crate::{function::{render::{rhi::RhiImpl, submit_render_data::{WebgpuPBRMaterial, WebgpuMesh, InstanceNode, WebgpuScene}, loader::ShaderLoader, render_resource::RenderResource, render_scene::{RenderScene}}, framework::resource::{material::MaterialId, mesh::MeshId}}, core::math::{Matrix4f}};

// pub struct RenderWebgpuMeshData {
//    pub mesh:            Rc<WebgpuMesh>,
//    pub instance_node:   Vec<InstanceNode>
// }

// pub struct RenderWebgpuPBRMateriaData {
//    pub material:        Rc<WebgpuPBRMaterial>,
//    pub mesh_instance:   HashMap<MeshId , RenderWebgpuMeshData>
// }

// pub struct MainCameraPass {
//     graphic_pipeline:               wgpu::RenderPipeline,
//     instance_group:                 wgpu::BindGroup,
//     instance_buffer:                wgpu::Buffer,
//     main_camera_draw_call_batch:    HashMap<MaterialId, RenderWebgpuPBRMateriaData>,

// }


// impl super::RenderPass for MainCameraPass {
//     fn new(
//         rhi:                    Rc<RefCell<RhiImpl>> , 
//         ) -> Self {
      
//         let shader = "assets/shader/mesh_shader.wgsl";

       

//         let shader = ShaderLoader::load(&rhi.borrow().device,shader);

//         let pbr_layouts     = WebgpuPBRMaterial::get_bind_group_layout(rhi.clone());
//         let camera_layouts  = WebgpuScene::get_bind_group_layout(rhi.clone());
        
//         let mut group_layouts = Vec::with_capacity(3);
//         group_layouts.push(&camera_layouts);


//         let instance_group_layout = rhi.borrow().device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
//             entries: &[
//                 wgpu::BindGroupLayoutEntry {
//                     ty: wgpu::BindingType::Buffer {
//                         ty: wgpu::BufferBindingType::Storage { read_only: true },
//                         has_dynamic_offset: false,
//                         min_binding_size: None,
//                     },
//                     count: None,
//                     binding: 0,
//                     visibility: wgpu::ShaderStages::VERTEX,
//                 }
//             ],
//             label: Some("instance node layout"),
//         });


//         group_layouts.push(&instance_group_layout);
//         group_layouts.push(&pbr_layouts);
        
  
//         let layout = rhi.borrow().device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
//             label: Some("Main Camera Pass Layout"),
//             bind_group_layouts: group_layouts.as_slice(),
//             push_constant_ranges: &[],
//         });

 
//         let primitive = wgpu::PrimitiveState {
//             topology: wgpu::PrimitiveTopology::TriangleList,
//             strip_index_format: None,
//             front_face: wgpu::FrontFace::Ccw,
//             cull_mode: Some(wgpu::Face::Back),
//             // cull_mode: None,
//             // Setting this to anything other than Fill requires Features::POLYGON_MODE_LINE
//             // or Features::POLYGON_MODE_POINT
//             polygon_mode: wgpu::PolygonMode::Fill,
//             // Requires Features::DEPTH_CLIP_CONTROL
//             unclipped_depth: false,
//             // Requires Features::CONSERVATIVE_RASTERIZATION
//             conservative: false,
//         };

//         let depth_stencil = Some(wgpu::DepthStencilState {
//             format: RenderResource::DEPTH_FORMAT,
//             depth_write_enabled: true,
//             depth_compare: wgpu::CompareFunction::Less, // 1.
//             stencil: wgpu::StencilState::default(), // 2.
//             bias: wgpu::DepthBiasState::default(),
//         });
//         let multisample = wgpu::MultisampleState {
//             count: 1,
//             mask: !0,
//             alpha_to_coverage_enabled: false,
//         };
//         let multiview = None;


//         let vertex = wgpu::VertexState {
//             module: &shader,
//             entry_point:"vs_main",
//             buffers: &[WebgpuMesh::get_vertex_layout()],
  
//         };

//         let fragment = wgpu::FragmentState {
//             module: &shader,
//             entry_point: "fs_main",
//             targets: &[Some(wgpu::ColorTargetState {
//                 format: wgpu::TextureFormat::Bgra8UnormSrgb,
//                 blend: Some(wgpu::BlendState {
//                     color:wgpu::BlendComponent {
//                         src_factor:wgpu::BlendFactor::SrcAlpha,
//                         dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
//                         operation: wgpu::BlendOperation::Add,
//                     },
//                     alpha:wgpu::BlendComponent {
//                         src_factor:wgpu::BlendFactor::SrcAlpha,
//                         dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
//                         operation: wgpu::BlendOperation::Add,
//                     },
//                 }),
//                 write_mask: wgpu::ColorWrites::ALL,
//             })],
  
//         };
        
//         let graphic_pipeline = rhi.borrow().device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
//             label: Some("main camera pass pipeline"),
//             layout: Some(&layout),
//             vertex: vertex,
//             fragment: Some(fragment),
//             primitive: primitive,
//             depth_stencil,
//             multisample,
//             multiview,
//         });

   


//         let instance_matrix = Matrix4f::identity();

//         let instance_buffer = rhi.borrow().device.create_buffer_init(
//             &wgpu::util::BufferInitDescriptor {
//                 label: Some("Instance Buffer"),
//                 contents: bytemuck::cast_slice(&[instance_matrix,instance_matrix,instance_matrix,instance_matrix,instance_matrix]),
//                 usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
//             }
//         );
//         let instance_group = rhi.borrow().device.create_bind_group(&wgpu::BindGroupDescriptor {
//             layout: &instance_group_layout,
//             entries: &[wgpu::BindGroupEntry {
//                 binding: 0,
//                 resource: instance_buffer.as_entire_binding(),
//             }],
//             label: Some("Instance_bind_group"),
//         });


//         Self {
//             graphic_pipeline,
   
//             instance_group,
//             instance_buffer,
//             main_camera_draw_call_batch: HashMap::new()
//         }
//     }
// }

// impl MainCameraPass {
//     // 
    



//     pub fn prepare_pass_data(&mut self , _rhi:Rc<RefCell<RhiImpl>> , _render_resource:&RenderResource){

//         // let global_group_data = render_resource.mesh_per_frame_ubo;

//         //  update buffer


//     }

//     pub fn draw<'pass>(&'pass mut self,render_pass:&mut wgpu::RenderPass<'pass> ,  rhi:Rc<RefCell<RhiImpl>> , render_scene:Rc<RefCell<RenderScene>> , webgpu_scene:&'pass WebgpuScene){
//         let mesh_nodes = &render_scene.borrow().main_camera_visible_mesh_nodes;

//         // HashMap<WebgpuPBRMaterial_Id , HashMap<WebgpuMesh_Id,Vec<InstanceNode>>>
        
//         self.main_camera_draw_call_batch.clear();
//         for mesh_node in mesh_nodes.iter() {
//             let mesh_instance = self.main_camera_draw_call_batch.entry(mesh_node.ref_material.resource_id).or_insert(RenderWebgpuPBRMateriaData { material: mesh_node.ref_material.clone(), mesh_instance: HashMap::new() });
//             let mesh_nodes = mesh_instance.mesh_instance.entry(mesh_node.ref_mesh.resource_id).or_insert(RenderWebgpuMeshData { mesh: mesh_node.ref_mesh.clone(), instance_node: Vec::new() });

//             let node = InstanceNode {
//                 model_matrix:mesh_node.model_matrix
//             };

//             mesh_nodes.instance_node.push(node);
//         }

//         render_pass.set_pipeline(&self.graphic_pipeline);

//         render_pass.set_bind_group(0, &webgpu_scene.global_group, &[]);
//         let mut instance_offset = 0;
//         for (_pbr_material,render_material_data) in &self.main_camera_draw_call_batch {
            
//             let pbr_material = &render_material_data.material;

//             let group = &pbr_material.material_group;
//             // bind material 
//             render_pass.set_bind_group(2, &group, &[]);
//             // bind vertex and index
//             // instance draw
         
//             for (_mesh,mesh_nodes) in &render_material_data.mesh_instance {
//                 let mesh = &mesh_nodes.mesh;
//                 let instance_node = &mesh_nodes.instance_node;

//                 let instance_model_matrix = instance_node.iter().map(|node| node.model_matrix).collect::<Vec<_>>();

//                 rhi.borrow().queue.write_buffer(&self.instance_buffer, (instance_offset * std::mem::size_of::<Matrix4f>()) as wgpu::BufferAddress, bytemuck::cast_slice(instance_model_matrix.as_slice()));

//                 render_pass.set_bind_group(1, &self.instance_group, &[]);

//                 render_pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
 
//                 render_pass.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
//                 render_pass.draw_indexed(0..(mesh.indics_count as u32), 0, instance_offset as u32..(instance_offset + instance_node.len()) as u32 );
//                 instance_offset += instance_node.len() ;
//             }

            
//         }


//     }
// }

